package ru.ifmo.itmokis.domain;

import java.io.Serializable;
import javax.persistence.Embeddable;

/**
 *
 * @author Ivan Stepuk
 */
@Embeddable
public class Time implements Comparable<Time>, Serializable {

    public static final Time ZERO = new Time(0);
    public static final Time ONE_HOUR = new Time(1);
    public static final Time ONE_DAY = new Time(1, 0);
    public static final Time ONE_WEEK = new Time(1, 0, 0);
    public static final int WORK_HOURS = 8;
    public static final int WORK_DAYS = 7;
    private int value;

    public Time(int weeks, int days, int hours) {
        value = WORK_DAYS * WORK_HOURS * weeks + WORK_HOURS * days + hours;
    }

    public Time(int days, int hours) {
        value = WORK_HOURS * days + hours;
    }

    public Time(int hours) {
        value = hours;
    }

    public Time() {
        value = 0;
    }

    public Time add(Time other) {
        return new Time(this.value + other.value);
    }

    public Time subtract(Time other) {
        return new Time(this.value - other.value);
    }

    @Override
    public String toString() {
        int weeks = value / (WORK_DAYS * WORK_HOURS);
        int days = (value - (WORK_DAYS * WORK_HOURS) * weeks) / WORK_HOURS;
        int hours = value - (WORK_DAYS * WORK_HOURS) * weeks - WORK_HOURS * days;
        StringBuilder sb = new StringBuilder();
        if (weeks > 0) {
            sb.append(weeks).append("w ");
        }
        if (days > 0) {
            sb.append(days).append("d ");
        }
        sb.append(hours).append("h");
        return sb.toString();
    }

    @Override
    public int compareTo(Time o) {
        return this.value - o.value;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Time other = (Time) obj;
        if (this.value != other.value) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 13 * hash + this.value;
        return hash;
    }

    protected int getValue() {
        return value;
    }

    protected void setValue(int value) {
        this.value = value;
    }

    public int toPlainHours() {
        return getValue();
    }
}
